package com.nc.menu.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.nc.menu.dao.MenuDao;
import com.nc.menu.dao.MenuPermissionDao;
import com.nc.menu.model.dto.MenuDto;
import com.nc.menu.model.entity.MenuEntity;
import com.nc.menu.model.entity.MenuPermissionsEntity;
import com.nc.menu.service.MenuService;
import com.plug.BeanUtil;
import com.plug.result.RetResponse;
import com.plug.result.RetResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 创建人:    xvzhe
 * 创建时间:
 * 修改时间:
 * 版本:      v1.0
 */
@Service
public class MenuServiceImpl implements MenuService {
    @Autowired
    MenuDao menuDao;
    @Autowired
    MenuPermissionDao menuPermissionDao;

    @Override
    @Transactional
    public RetResult save(MenuDto menuDto) {
        try {
            MenuEntity menuEntity = menuDao.save(BeanUtil.convertToBean(menuDto, MenuEntity.class));
            menuPermissionDao.deleteByMenuId(menuEntity.getId());
            menuDto.getPermissions().stream().forEach(per -> {
                MenuPermissionsEntity menuPermissionsEntity = new MenuPermissionsEntity();
                menuPermissionsEntity.setMenuId(menuEntity.getId());
                menuPermissionsEntity.setPermission(per);
                menuPermissionDao.save(menuPermissionsEntity);
            });
            return RetResponse.makeOKRsp();
        } catch (Exception e) {
            return RetResponse.makeErrRsp();
        }
    }

    @Override
    public RetResult findByPermissions(List<String> permission) {
        List<MenuEntity> entity = menuDao.findByPermissions(permission);
        List<MenuDto> dto = Lists.newLinkedList();
        entity.stream().forEach(ls -> {
            dto.add(BeanUtil.convertToBean(ls, MenuDto.class));
        });
        return RetResponse.makeOKRsp(menuSort(dto));
    }

    @Override
    public RetResult findAll(String userId) {
        return RetResponse.makeOKRsp(menuSort(findMenu(userId)));
    }

    private List<MenuDto> findMenu(String userId) {
        List<String> roleCode = Lists.newArrayList();
        List<MenuEntity> entity = menuDao.findByStatusAndUserId(true, userId);
        List<MenuDto> dto = Lists.newLinkedList();
        entity.stream().forEach(ls -> {
            List<MenuPermissionsEntity> per = menuPermissionDao.findByMenuId(ls.getId());
            MenuDto menuDto = BeanUtil.convertToBean(ls, MenuDto.class);
            menuDto.setPermissions(per.stream().map(MenuPermissionsEntity::getPermission).collect(Collectors.toSet()));
            dto.add(menuDto);
        });
        return dto;
    }

    private List<MenuDto> menuSort(List<MenuDto> menuDtos) {
        Map<Integer, List<MenuDto>> mp = menuDtos.stream()
                .collect(Collectors.groupingBy(MenuDto::getSeries));
        mp.keySet().stream().forEach(key -> {
            mp.get(key).stream().forEach(th -> {
                Optional.ofNullable(mp.get(key + 1)).orElseGet(() -> {
                    return Lists.newLinkedList();
                }).stream().forEach(son -> {
                    if (th.getId().equals(son.getParentId())) {
                        List<MenuDto> child = th.getChild() == null ? Lists.newLinkedList()
                                : th.getChild();
                        child.add(son);
                        th.setChild(child);
                    }
                });
            });
        });
        return mp.get(1);
    }

    @Override
    public RetResult findNo(MenuDto menuDto) {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<MenuEntity> example = Example.of(BeanUtil.convertToBean(menuDto, MenuEntity.class), matcher);
        List<MenuDto> dto = Lists.newLinkedList();
        List<MenuEntity> entity = menuDao.findAll(example);
        entity.stream().sorted(Comparator.comparing(MenuEntity::getOrders)).forEach(ls -> {
            List<MenuPermissionsEntity> per = menuPermissionDao.findByMenuId(ls.getId());
            MenuDto mDto = BeanUtil.convertToBean(ls, MenuDto.class);
            mDto.setPermissions(per.stream().map(MenuPermissionsEntity::getPermission).collect(Collectors.toSet()));
            dto.add(mDto);
        });
        return RetResponse.makeOKRsp(dto);
    }
}


